#include <D3D9Renderer.h>

DXRenderer* g_pRenderer = NULL;

DXRenderer::DXRenderer()
{
	m_hWnd = NULL;
	ZeroMemory(&m_d3dpp, sizeof(m_d3dpp));

	g_pRenderer = this;
}

DXRenderer::~DXRenderer()
{
	SAFE_RELEASE(m_pSpriteHandler);
	SAFE_RELEASE(m_pBackbuffer);
	SAFE_RELEASE(m_pDevice);
	SAFE_RELEASE(m_pD3D);
}

bool DXRenderer::Init(HWND hWnd ,int screenWidth, int screenHeight, int colorDepth, bool fullscreen)
{
	m_hWnd = hWnd;
	D3DDEVTYPE devType = D3DDEVTYPE_HAL;
	DWORD requestedVP = D3DCREATE_HARDWARE_VERTEXPROCESSING;

	if(m_hWnd == NULL)
		return false;

	//Create IDirect3D9 Object
	m_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
	if (!m_pD3D)
		return false;

	//Verify hardware support for specified formats in windowed and full screen modes
	D3DDISPLAYMODE mode;
	m_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &mode);
	HR(m_pD3D->CheckDeviceType(D3DADAPTER_DEFAULT, devType, mode.Format, mode.Format, true));
	HR(m_pD3D->CheckDeviceType(D3DADAPTER_DEFAULT, devType, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, false));

	//Check for requested vertex processing and pure device
	D3DCAPS9 caps;
	HR(m_pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, devType, &caps));

	DWORD devBehaviorFlags = 0;
	if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
		devBehaviorFlags |= requestedVP;
	else
		devBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;

	// If pure device and HW T&L supported
	if( caps.DevCaps & D3DDEVCAPS_PUREDEVICE &&
		devBehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING)
			devBehaviorFlags |= D3DCREATE_PUREDEVICE;

		
	//Fill out the D3DPRESENT_PARAMETERS structure
	m_d3dpp.BackBufferWidth			   = screenWidth;
	m_d3dpp.BackBufferHeight		   = screenHeight;
	if (fullscreen)
		m_d3dpp.BackBufferFormat       = D3DFMT_X8R8G8B8;	
	else
		m_d3dpp.BackBufferFormat       = D3DFMT_UNKNOWN;
	m_d3dpp.BackBufferCount            = 1;
	m_d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;
	m_d3dpp.MultiSampleQuality         = 0;
	m_d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD; 
	m_d3dpp.hDeviceWindow              = m_hWnd;
	m_d3dpp.Windowed                   = (!fullscreen);
	m_d3dpp.EnableAutoDepthStencil     = true; 
	m_d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;
	m_d3dpp.Flags                      = 0;
	m_d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
	m_d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;

	//Create the device.
	HR(m_pD3D->CreateDevice(
		D3DADAPTER_DEFAULT,			// primary adapter
		devType,					// device type
		m_hWnd,    // window associated with device
		devBehaviorFlags,			// vertex processing
		&m_d3dpp,						// present parameters
		&m_pDevice));				 // return created device

	if(m_pDevice == NULL)
		return false;

	//clear the backbuffer to black
	HR(m_pDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xfff00fff, 1.0f, 0));
	
	//create pointer to the back buffer
	HR(m_pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &m_pBackbuffer));

	if (m_pBackbuffer == NULL)
		return false;

	//init 2D renderer
	HR(D3DXCreateSprite(m_pDevice, &m_pSpriteHandler));

	if (m_pSpriteHandler == NULL)
		return false;

	return true;
}

void DXRenderer::TestRender()
{
	HR(g_pRenderer->GetDevice()->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff33ffff, 1.0f, 0));

	HR(g_pRenderer->GetDevice()->BeginScene());
	HR(g_pRenderer->GetDevice()->EndScene() );
	HR(g_pRenderer->GetDevice()->Present(0,0,0,0));
}